package com.lihao.walkers.map;

import java.util.ArrayList;
import java.util.List;

import com.amap.api.location.AMapLocation;
import com.amap.api.location.AMapLocationListener;
//import com.amap.api.location.LocationManagerProxy;
//import com.amap.api.location.LocationProviderProxy;
import com.amap.api.maps2d.AMap;
import com.amap.api.maps2d.AMap.OnMapClickListener;
import com.amap.api.maps2d.CameraUpdateFactory;
import com.amap.api.maps2d.LocationSource;
import com.amap.api.maps2d.MapView;
import com.amap.api.maps2d.model.BitmapDescriptorFactory;
import com.amap.api.maps2d.model.CircleOptions;
import com.amap.api.maps2d.model.LatLng;
import com.amap.api.maps2d.model.MarkerOptions;
import com.amap.api.maps2d.model.MyLocationStyle;
import com.amap.api.services.core.AMapException;
import com.amap.api.services.core.LatLonPoint;
import com.amap.api.services.core.PoiItem;
import com.amap.api.services.core.ServiceSettings;
import com.amap.api.services.poisearch.PoiResult;
import com.amap.api.services.poisearch.PoiSearch;
import com.amap.api.services.poisearch.PoiSearch.OnPoiSearchListener;
import com.amap.api.services.poisearch.PoiSearch.SearchBound;
import com.lihao.walkers.R;
import com.lihao.walkers.dialog.AroundSettingDialog;
import com.lihao.walkers.dialog.SearchPOISettingDialog;
import com.lihao.walkers.fork.OriginActivity;
import com.lihao.walkers.surfaceview.SurfaceActivity;
import com.lihao.walkers.utils.Constants;

import android.content.Intent;
import android.graphics.Color;
import android.location.Location;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.animation.ScaleAnimation;
import android.view.animation.TranslateAnimation;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.RelativeLayout.LayoutParams;

/**
 * 地图。
 * @author lihao
 */
public class MapActivity extends OriginActivity implements OnClickListener,
		AMap.OnMyLocationChangeListener, OnPoiSearchListener, OnMapClickListener {

	private AMap mAMap = null;

	private MapView mMapView = null;

	private AMap.OnMyLocationChangeListener mListener = null;

//	private LocationManagerProxy mAMapLocationManager = null;

	/** 是否已经添加过了自身范围标记。 */
	private boolean mAroundMarked = false;

	/** 当前的纬度。 */
	private double mCurrentLat = -1;

	/** 当前的经度。 */
	private double mCurrentLon = -1;

	/** 去周边搜索设置页面的intent。 */
	private Intent mToAroundSetting = null;

	/** 去相机视图区域的intent。 */
	private Intent mToSurfaceView = null;

	/** 去POI搜索页面的intent。 */
	private Intent mToSearchPOISetting = null;

	/** 按钮面板。 */
	private LinearLayout mControlPanel = null;

	/** 周边按钮。 */
	private Button mBtnAround = null;

	/** 开始追踪按钮。 */
	private Button mBtnStartWalking = null;

	/** 查找按钮。 */
	private Button mBtnSearch = null;

	/** 地图视图动画。 */
	private ScaleAnimation mMapViewAnim = null;

	/** 周边按钮动画。 */
	private TranslateAnimation mAroundAnim = null;

	/** 开始追踪按钮动画。 */
	private TranslateAnimation mStartWalkingAnim = null;

	/** 查找按钮动画。 */
	private TranslateAnimation mSearchAnim = null;

	/** 单一目标提示框动画。 */
	private TranslateAnimation mOneTargetAnim = null;

	/** 多个目标形成的目标列表。 */
	private List<LocationBean> mTargetList = new ArrayList<LocationBean>();

	/** 单一目标。 */
	private LocationBean mOneTarget = null;

	/** 单一目标提示框。 */
	private TextView mOneTargetView = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.map_layout);
		mMapView = (MapView) findViewById(R.id.mvMapView);
		mMapView.onCreate(savedInstanceState);
		receiveConfigInfo();
		init();
	}

	@Override
	protected void onSaveInstanceState(Bundle outState) {
		super.onSaveInstanceState(outState);
		mMapView.onSaveInstanceState(outState);
	}

	@Override
	protected void onResume() {
		super.onResume();
		mMapView.onResume();
	}

	@Override
	protected void onPause() {
		super.onPause();
		mMapView.onPause();
//		deactivate();
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		mMapView.onDestroy();
//		deactivate();
	}

	@Override
	public void onClick(View v) {
		int buttonID = v.getId();
		if (buttonID == R.id.btnAroundMe) {
			mToAroundSetting.putExtra(Constants.CURRENT_LAT, mCurrentLat);
			mToAroundSetting.putExtra(Constants.CURRENT_LON, mCurrentLon);
			startActivityForResult(mToAroundSetting, Constants.RECEIVE_AROUND_SETTINGS);
		} else if (buttonID == R.id.btnStartWalking) { // 回传数据。
			if((mTargetList == null || mTargetList.size() == 0)
					&& mOneTarget == null){
				Toast.makeText(this, getString(R.string.no_target), Toast.LENGTH_SHORT).show();
			} else {
				DataPackage dataPackage = new DataPackage();
				if(mOneTarget == null){ // 没有单一目标，追踪多个目标。
					dataPackage.setDataType(Constants.DATA_MULTI);
					dataPackage.setMultiLocation(mTargetList);
				} else { // 追踪单个目标。
					dataPackage.setDataType(Constants.DATA_SINGLE);
					dataPackage.setSingleLocation(mOneTarget);
				}
				mToSurfaceView.putExtra(Constants.RECEIVE_LOCATION_DATA, dataPackage);
				mToSurfaceView.putExtra(Constants.CURRENT_LAT, mCurrentLat);
				mToSurfaceView.putExtra(Constants.CURRENT_LON, mCurrentLon);
				setResult(Constants.RECEIVE_POINTS, mToSurfaceView);
				finish();
			}
		} else if (buttonID == R.id.btnSearchPOI) {
			mToSearchPOISetting.putExtra(Constants.CURRENT_LAT, mCurrentLat);
			mToSearchPOISetting.putExtra(Constants.CURRENT_LON, mCurrentLon);
			startActivityForResult(mToSearchPOISetting, Constants.RECEIVE_SEARCH_POI_SETTINGS);
		} else if (buttonID == R.id.tvOneTarget) { // 单击中部提示条。
			mOneTarget = null; // 取消单一目标跟踪。
			mOneTargetView.setVisibility(View.INVISIBLE); // 隐藏。
			if(mTargetList != null && mTargetList.size() > 0){ // 之前确定过多个目标。
				Toast.makeText(this,
						getString(R.string.continue_track_multi_targets), Toast.LENGTH_SHORT).show();
			}
		}
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
		super.onActivityResult(requestCode, resultCode, data);
		if(mAroundMarked && data != null){ // 已经定位之后才能进行周边查找。
			double searchLat = data.getExtras().getDouble(Constants.CURRENT_LAT);
			double searchLon = data.getExtras().getDouble(Constants.CURRENT_LON);
			String keyWorlds = null;
			PoiSearch.Query onceQuery = null;
			PoiSearch onceSearch = null;
			LatLonPoint currentLocation = null;
			switch (requestCode) {
				case Constants.RECEIVE_AROUND_SETTINGS:
					keyWorlds = data.getExtras().getString(Constants.AROUND_SEARCH_KEY_WORDS);
					onceQuery = new PoiSearch.Query("", keyWorlds, "");
					currentLocation = new LatLonPoint(searchLat, searchLon);
					SearchBound searchBound = new SearchBound(currentLocation, Constants.AROUND_CIRCLE_RADIUS);
					try {
						// 确保隐私合规。
						ServiceSettings.updatePrivacyShow(this, true, true);
						ServiceSettings.updatePrivacyAgree(this, true);
						// 开始搜索。
						onceSearch = new PoiSearch(this, onceQuery);
						onceSearch.setBound(searchBound);
						onceSearch.setOnPoiSearchListener(this);
						onceSearch.searchPOIAsyn();
					} catch (AMapException e) {
						e.printStackTrace();
					}
					break;
				case Constants.RECEIVE_SEARCH_POI_SETTINGS:
					keyWorlds = data.getExtras().getString(Constants.SEARCH_POI_KEY_WORD);
					String searchCity = data.getExtras().getString(Constants.SEARCH_POI_KEY_CITY);
					onceQuery = new PoiSearch.Query(keyWorlds, "", searchCity);
					currentLocation = new LatLonPoint(searchLat, searchLon);
					try {
						// 确保隐私合规。
						ServiceSettings.updatePrivacyShow(this, true, true);
						ServiceSettings.updatePrivacyAgree(this, true);
						// 开始搜索。
						onceSearch = new PoiSearch(this, onceQuery);
						onceSearch.setOnPoiSearchListener(this);
						onceSearch.searchPOIAsyn();
					} catch (AMapException e) {
						e.printStackTrace();
					}
					break;
				default:
					break;
			}
		}
	}

//	@Override
//	public void activate(OnLocationChangedListener listener) {
//		mListener = listener;
//		if(mAMapLocationManager == null){
//			mAMapLocationManager = LocationManagerProxy.getInstance(this);
//			mAMapLocationManager.requestLocationUpdates(
//					LocationProviderProxy.AMapNetwork, 2000, 10, this);
//		}
//	}

//	@Override
//	public void deactivate() {
//		mListener = null;
//		if (mAMapLocationManager != null) {
//			mAMapLocationManager.removeUpdates(this);
//			mAMapLocationManager.destroy();
//		}
//		mAMapLocationManager = null;
//	}

//	@Override
//	public void onLocationChanged(AMapLocation aLocation) {
//		if (mListener != null && aLocation != null) {
//			mListener.onLocationChanged(aLocation);
//			mCurrentLat = aLocation.getLatitude();
//			mCurrentLon = aLocation.getLongitude();
//			if(!mAroundMarked){
//				mAroundMarked = true;
//			}
//		}
//	}

	@Override
	public void onPoiItemSearched(PoiItem result, int rCode) {

	}

	@Override
	public void onPoiSearched(PoiResult result, int rCode) {
		mAMap.clear(); // 清除覆盖物，准备添加新的。
		LatLng location = new LatLng(mCurrentLat, mCurrentLon);
		mAMap.addMarker(newMarker(location, R.drawable.location_marker_green, null));
		if(rCode == 1000 && result != null){ // 搜索成功。
			List<PoiItem> pois = result.getPois();
			if(pois != null && pois.size() > 0){
				mAMap.addCircle(newCircle(location, Constants.AROUND_CIRCLE_RADIUS));
				mTargetList.clear(); // 清空原有的目标列表。
				mOneTarget = null; // 将单一目标置空。
				mOneTargetView.setVisibility(View.INVISIBLE); // 设置单一目标提示为不可见。
				int i = 0;
				int total = pois.size();
				for (; i < total; i++) {
					PoiItem onePoi = pois.get(i);
					LatLonPoint poiLocation = onePoi.getLatLonPoint();
					double latitude = poiLocation.getLatitude();
					double longitude = poiLocation.getLongitude();
					LatLng oneLocation = new LatLng(latitude, longitude);
					mAMap.addMarker(newMarker(
							oneLocation, R.drawable.location_marker_yellow, onePoi.getTitle()));
					mTargetList.add(new LocationBean(latitude, longitude, onePoi.getTitle()));
				}
				Toast.makeText(
						this, getString(R.string.track_multi_targets), Toast.LENGTH_SHORT).show();
				pois.clear();
			} else {
				Toast.makeText(this, getString(R.string.no_result), Toast.LENGTH_SHORT).show();
			}
		}
	}

	@Override
	public void onMapClick(LatLng location) {
		if(mOneTarget == null){ // 建立新的单一目标信息。
			mOneTarget = new LocationBean(location.latitude, location.longitude, null);
		} else { // 更新单一目标信息。
			mOneTarget.setLatitude(location.latitude);
			mOneTarget.setLongitude(location.longitude);
		}
		Toast.makeText(this, getString(R.string.one_target_tip), Toast.LENGTH_SHORT).show();
		mOneTargetView.setText(
				getString(R.string.start_tracking).concat(":(")
						.concat(String.valueOf(location.latitude)).concat(",")
						.concat(String.valueOf(location.longitude)).concat(")"));
		mOneTargetView.setVisibility(View.VISIBLE); // 设置中间的提示横条可见。
		mOneTargetView.startAnimation(mOneTargetAnim); // 开始动画。
	}

	/**
	 * 获得传过来的配置信息。
	 */
	private void receiveConfigInfo(){
		Bundle bundle = getIntent().getExtras();
		setScreenWidth(bundle.getInt(Constants.SCREEN_WIDTH));
		setScreenHeight(bundle.getInt(Constants.SCREEN_HEIGHT));
	}

	/**
	 * 初始化视图。
	 */
	private void init(){
		initAnims();
		initIntents();
		initAMap();
		mMapView.startAnimation(mMapViewAnim);
		initControlPanel();
		initFunctionButtons();
	}

	/**
	 * 初始化动画。
	 */
	private void initAnims(){
		mMapViewAnim = new ScaleAnimation(1.2f, 1.0f, 1.2f, 1.0f);
		mMapViewAnim.setStartOffset(1000);
		mMapViewAnim.setDuration(500);
		mAroundAnim = createAnims(1250);
		mStartWalkingAnim = createAnims(1400);
		mSearchAnim = createAnims(1550);
	}

	/**
	 * 初始化转向用的intent。
	 */
	private void initIntents(){
		mToAroundSetting = new Intent(this, AroundSettingDialog.class);
		mToAroundSetting.putExtra(Constants.SCREEN_WIDTH, getScreenWidth());
		mToAroundSetting.putExtra(Constants.SCREEN_HEIGHT, getScreenHeight());
		mToSearchPOISetting = new Intent(this, SearchPOISettingDialog.class);
		mToSearchPOISetting.putExtra(Constants.SCREEN_WIDTH, getScreenWidth());
		mToSearchPOISetting.putExtra(Constants.SCREEN_HEIGHT, getScreenHeight());
		mToSurfaceView = new Intent(this, SurfaceActivity.class);
	}

	/**
	 * 初始化mAMap对象。
	 */
	private void initAMap(){
		if (mAMap == null) {
			mAMap = mMapView.getMap();
			mAMap.setOnMapClickListener(this); // 为地图添加点击事件。
			setUpMap();
		}
	}

	/**
	 * 设置一些amap的属性
	 */
	private void setUpMap() {
		MyLocationStyle myLocationStyle = new MyLocationStyle();
		myLocationStyle.myLocationType(MyLocationStyle.LOCATION_TYPE_FOLLOW);
		myLocationStyle.interval(1000);
		myLocationStyle.myLocationIcon(BitmapDescriptorFactory.fromResource(R.drawable.location_marker_green));
		myLocationStyle.strokeColor(Color.BLACK);
		myLocationStyle.strokeWidth(1.0f);
		myLocationStyle.radiusFillColor(Color.argb(20, 177, 0, 0));
		myLocationStyle.showMyLocation(true);
		mAMap.setMyLocationStyle(myLocationStyle); // 绘制自身位置图标。
		mAMap.setOnMyLocationChangeListener(this);
		mAMap.getUiSettings().setMyLocationButtonEnabled(true);
		mAMap.setMyLocationEnabled(true);
		// 放大地图。
		float zoomPer = (mAMap.getMaxZoomLevel() - mAMap.getMinZoomLevel()) * 0.7f;
		mAMap.moveCamera(CameraUpdateFactory.zoomTo(mAMap.getMinZoomLevel() + zoomPer)); // 放大地图。
	}

	/**
	 * 生成按钮动画。
	 * @param offset 开始动画的推迟时间。
	 * @return 线性动画。
	 */
	private TranslateAnimation createAnims(long offset){
		int smallerSize = Math.min(getScreenWidth(), getScreenHeight());
		TranslateAnimation anim = new TranslateAnimation(0, 0,
				-smallerSize * Constants.MAIN_BUTTON_WIDTH, 0);
		anim.setStartOffset(offset);
		anim.setDuration(400);
		return anim;
	}

	/**
	 * 初始化下部控制面板。
	 */
	private void initControlPanel(){
		int smallerSize = Math.min(getScreenWidth(), getScreenHeight());
		mControlPanel = (LinearLayout) findViewById(R.id.llControlPanel);
		RelativeLayout.LayoutParams ctrlPanelLp = (LayoutParams) mControlPanel.getLayoutParams();
		ctrlPanelLp.height = (int) (smallerSize * Constants.MAIN_BUTTON_WIDTH);
		ctrlPanelLp.alignWithParent = true;
	}

	/**
	 * 初始化功能按钮。
	 */
	private void initFunctionButtons(){
		mBtnAround = (Button) findViewById(R.id.btnAroundMe);
		mBtnAround.setOnClickListener(this);
		mBtnStartWalking = (Button) findViewById(R.id.btnStartWalking);
		mBtnStartWalking.setOnClickListener(this);
		mBtnSearch = (Button) findViewById(R.id.btnSearchPOI);
		mBtnSearch.setOnClickListener(this);
		initOneTargetView();
		buttonsEnter();
	}

	/**
	 * 初始化单一目标提示view。
	 */
	private void initOneTargetView(){
		mOneTargetView = (TextView) findViewById(R.id.tvOneTarget);
		RelativeLayout.LayoutParams oneLp =
				(LayoutParams) mOneTargetView.getLayoutParams();
		oneLp.height = mControlPanel.getLayoutParams().height; // 确定中间提示条的高度。
		mOneTargetView.setOnClickListener(this);
		initOneTargetViewAnim(oneLp.height);
	}

	/**
	 * 初始化单一目标提示框的动画。
	 * @param tipheight 提示按钮的高度。
	 */
	private void initOneTargetViewAnim(int tipheight){
		mOneTargetAnim = new TranslateAnimation(
				0, 0, -((getScreenHeight() + tipheight) >> 1), 0);
		mOneTargetAnim.setDuration(500);
	}

	/**
	 * 执行按钮的进入动画。
	 */
	private void buttonsEnter(){
		mBtnAround.startAnimation(mAroundAnim);
		mBtnSearch.startAnimation(mSearchAnim);
		mBtnStartWalking.startAnimation(mStartWalkingAnim);
	}

	/**
	 * 创建一个圆形覆盖物。
	 * @param location 中心点坐标。
	 * @param radius 半径。
	 * @return 圆形覆盖物。
	 */
	private CircleOptions newCircle(LatLng location, double radius){
		CircleOptions circle = new CircleOptions();
		circle.center(location);
		circle.radius(radius);
		circle.strokeColor(Color.BLACK);
		circle.strokeWidth(1);
		circle.fillColor(Color.argb(20, 177, 0, 0));
		return circle;
	}

	/**
	 * 生成一个标记。
	 * @param location 标记的位置。
	 * @param iconID 标记用到的图片ID。
	 * @param title 需要显示的标题，可以为null。
	 * @return 标记。
	 */
	private MarkerOptions newMarker(LatLng location, int iconID, String title){
		MarkerOptions marker = new MarkerOptions();
		marker.position(location);
		marker.anchor(0, 0.5f);
		marker.icon(BitmapDescriptorFactory.fromResource(iconID));
		if(title != null){
			marker.title(title);
		}
		return marker;
	}

	@Override
	public void onMyLocationChange(Location location) {
		mCurrentLat = location.getLatitude();
		mCurrentLon = location.getLongitude();
		if (!mAroundMarked) {
			mAroundMarked = true;
		}
		Log.e("stats", "lat: " + mCurrentLat + ", lon: " + mCurrentLon);
	}
}
